home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / GW AdaEd 1.4.2 / GWAdaDemos / NYUDemos / PAGER_PART1.ADA < prev    next >
Text File  |  1994-01-09  |  13KB  |  436 lines

  1. -- PROGRAM/CODE BODY NAME:    PAGER2
  2. -- AUTHOR:            Richard Conn
  3. -- VERSION:            1.1
  4. -- DATE:            6/12/89
  5. -- REVISION HISTORY -
  6. -- Version    Date    Author        Comments
  7. --    1.0    8/28/87    Richard Conn    Initial
  8. --    1.1       6/12/89 Richard Conn    CLI interface added
  9. -- KEYWORDS -
  10. --    pager, pager2, paged files, page, unpage
  11. -- CALLING SYNTAX -
  12. --    From the command line: pager2
  13. --    From the command line: pager2 verb arguments
  14. -- EXTERNAL ROUTINES -
  15. --    Package CLI
  16. --    Package TEXT_IO
  17. -- DESCRIPTION -
  18. --    PAGER2 assembles, extracts elements from, and lists paged files.
  19. -- Paged files are text files which contain one or more component files
  20. -- prefixed by a banner like:
  21. --
  22. --    ::::::::::
  23. --    filename
  24. --    ::::::::::
  25. --
  26. -- or
  27. --
  28. --    --::::::::::
  29. --    --filename
  30. --    --::::::::::
  31. --
  32. --    PAGER2 will manipulate paged files whose components
  33. -- are prefixed with either banner, but it assembles paged files with only
  34. -- the second banner (beginning with the Ada comment characters).
  35.  
  36. --===========================================================================
  37. -------------------------- PACKAGE LINE_DEFINITION --------------------------
  38. --===========================================================================
  39.  
  40. -- The following package defines an object of type LINE
  41. package LINE_DEFINITION is
  42.  
  43.     -- The maximum length of a line
  44.     MAX_LINE_LENGTH : constant NATURAL := 200;
  45.  
  46.     -- Type definition for LINE
  47.     type LINE is record
  48.     CONTENT : STRING(1 .. MAX_LINE_LENGTH);
  49.     LAST    : NATURAL;
  50.     end record;
  51.     type LINE_LIST_ELEMENT;
  52.     type LINE_LIST        is access LINE_LIST_ELEMENT;
  53.     type LINE_LIST_ELEMENT is record
  54.     CONTENT : LINE;
  55.     NEXT    : LINE_LIST;
  56.     end record;
  57.  
  58.     -- Banners
  59.     COMMENT_BANNER  : constant STRING  := "--::::::::::";
  60.     BANNER          : constant STRING  := "::::::::::";
  61.  
  62.     -- Convert strings to LINEs and back
  63.     function CONVERT(FROM : in STRING) return LINE;
  64.     function CONVERT(FROM : in LINE) return STRING;
  65.  
  66.     -- Convert a LINE to lower-case characters
  67.     procedure TOLOWER(ITEM : in out LINE);
  68.     function TOLOWER(ITEM : in LINE) return LINE;
  69.  
  70. end LINE_DEFINITION;
  71.  
  72. package body LINE_DEFINITION is
  73.  
  74.     -- Convert strings to LINEs
  75.     function CONVERT(FROM : in STRING) return LINE is
  76.     TO : LINE_DEFINITION.LINE;
  77.     begin
  78.     TO.CONTENT(TO.CONTENT'FIRST .. TO.CONTENT'FIRST + FROM'LENGTH - 1) :=
  79.       FROM;
  80.     TO.LAST := FROM'LENGTH;
  81.     return TO;
  82.     end CONVERT;
  83.  
  84.     function CONVERT(FROM : in LINE) return STRING is
  85.     begin
  86.     return FROM.CONTENT(FROM.CONTENT'FIRST .. FROM.LAST);
  87.     end CONVERT;
  88.  
  89.     procedure TOLOWER(ITEM : in out LINE) is
  90.     begin
  91.     for I in ITEM.CONTENT'FIRST .. ITEM.LAST loop
  92.         if ITEM.CONTENT(I) in 'A' .. 'Z' then
  93.         ITEM.CONTENT(I) :=
  94.                   CHARACTER'VAL(CHARACTER'POS(ITEM.CONTENT(I)) -
  95.           CHARACTER'POS('A') + CHARACTER'POS('a'));
  96.         end if;
  97.     end loop;
  98.     end TOLOWER;
  99.  
  100.     function TOLOWER(ITEM : in LINE) return LINE is
  101.         MYLINE : LINE;
  102.     begin
  103.         MYLINE := ITEM;
  104.         TOLOWER(MYLINE);
  105.         return MYLINE;
  106.     end TOLOWER;
  107.  
  108. end LINE_DEFINITION;
  109.  
  110. --===========================================================================
  111. -------------------------- PACKAGE INPUT_FILE -------------------------------
  112. --===========================================================================
  113.  
  114. -- The following package manipulates an object called an INPUT_FILE,
  115. -- which is a text file that is composed of objects of type LINE.
  116. -- LINEs can only be read from an INPUT_FILE.
  117. with LINE_DEFINITION;
  118. package INPUT_FILE is
  119.  
  120.     -- Open the input file
  121.     -- Exceptions which may be raised: FILE_NOT_FOUND, FILE_ALREADY_OPEN
  122.     procedure OPEN(FILE_NAME : in STRING);
  123.     procedure OPEN(FILE_NAME : in LINE_DEFINITION.LINE);
  124.  
  125.     -- Close the input file
  126.     -- Exceptions which may be raised: FILE_NOT_OPEN
  127.     procedure CLOSE;
  128.  
  129.     -- Read a line from the input file
  130.     -- Exceptions which may be raised: FILE_NOT_OPEN, READ_PAST_END_OF_FILE
  131.     procedure READ(TO : out LINE_DEFINITION.LINE);
  132.  
  133.     -- Return TRUE if the input file is empty (no more lines remain)
  134.     -- Exceptions which may be raised: FILE_NOT_OPEN
  135.     function END_OF_FILE return BOOLEAN;
  136.  
  137.     -- Exceptional conditions
  138.     FILE_NOT_FOUND        : exception;
  139.     FILE_ALREADY_OPEN     : exception;
  140.     FILE_NOT_OPEN         : exception;
  141.     READ_PAST_END_OF_FILE : exception;
  142.  
  143. end INPUT_FILE;
  144.  
  145. with TEXT_IO;
  146. package body INPUT_FILE is
  147.  
  148.     -- The file descriptor for the input file
  149.     FD : TEXT_IO.FILE_TYPE;
  150.  
  151.     -- Open the input file
  152.     procedure OPEN(FILE_NAME : in STRING) is
  153.     begin
  154.     TEXT_IO.OPEN(FD, TEXT_IO.IN_FILE, FILE_NAME);
  155.     exception
  156.     when TEXT_IO.NAME_ERROR =>
  157.         raise FILE_NOT_FOUND;
  158.     when TEXT_IO.STATUS_ERROR =>
  159.         raise FILE_ALREADY_OPEN;
  160.     end OPEN;
  161.  
  162.     procedure OPEN(FILE_NAME : in LINE_DEFINITION.LINE) is
  163.     begin
  164.     OPEN(LINE_DEFINITION.CONVERT(FILE_NAME));
  165.     end OPEN;
  166.  
  167.     -- Close the input file
  168.     procedure CLOSE is
  169.     begin
  170.     TEXT_IO.CLOSE(FD);
  171.     exception
  172.     when TEXT_IO.STATUS_ERROR =>
  173.         raise FILE_NOT_OPEN;
  174.     end CLOSE;
  175.  
  176.     -- Read a line from the input file
  177.     procedure READ(TO : out LINE_DEFINITION.LINE) is
  178.     begin
  179.     TEXT_IO.GET_LINE(FD, TO.CONTENT, TO.LAST);
  180.     exception
  181.     when TEXT_IO.END_ERROR =>
  182.         raise READ_PAST_END_OF_FILE;
  183.     when TEXT_IO.STATUS_ERROR =>
  184.         raise FILE_NOT_OPEN;
  185.     end READ;
  186.  
  187.     -- Return TRUE if the input file is empty (no more lines remain)
  188.     function END_OF_FILE return BOOLEAN is
  189.     begin
  190.     return TEXT_IO.END_OF_FILE(FD);
  191.     exception
  192.     when TEXT_IO.STATUS_ERROR =>
  193.         raise FILE_NOT_OPEN;
  194.     end END_OF_FILE;
  195.  
  196. end INPUT_FILE;
  197.  
  198. --===========================================================================
  199. -------------------------- PACKAGE OUTPUT_FILE ------------------------------
  200. --===========================================================================
  201.  
  202. -- The following package manipulates an object called an OUTPUT_FILE,
  203. -- which is a text file that is composed of objects of type LINE.
  204. -- LINEs can only be written to an OUTPUT_FILE.
  205. with LINE_DEFINITION;
  206. package OUTPUT_FILE is
  207.  
  208.     -- Open the output file
  209.     -- Exceptions which may be raised: CANNOT_CREATE_FILE, FILE_ALREADY_OPEN
  210.     procedure OPEN(FILE_NAME : in STRING);
  211.     procedure OPEN(FILE_NAME : in LINE_DEFINITION.LINE);
  212.  
  213.     -- Close the output file
  214.     -- Exceptions which may be raised: FILE_NOT_OPEN
  215.     procedure CLOSE;
  216.  
  217.     -- Write a line to the output file
  218.     -- Exceptions which may be raised: FILE_NOT_OPEN, DISK_FULL
  219.     procedure WRITE(FROM : in LINE_DEFINITION.LINE);
  220.     procedure WRITE(FROM : in STRING);
  221.  
  222.     -- Exceptional conditions
  223.     CANNOT_CREATE_FILE : exception;
  224.     FILE_ALREADY_OPEN  : exception;
  225.     FILE_NOT_OPEN      : exception;
  226.     DISK_FULL          : exception;
  227.  
  228. end OUTPUT_FILE;
  229.  
  230. with TEXT_IO;
  231. package body OUTPUT_FILE is
  232.  
  233.     -- File descriptor for the output file
  234.     FD : TEXT_IO.FILE_TYPE;
  235.  
  236.     -- Open the output file
  237.     procedure OPEN(FILE_NAME : in STRING) is
  238.     INLINE : STRING(1 .. 80);
  239.     LAST   : NATURAL;
  240.     begin
  241.     TEXT_IO.CREATE(FD, TEXT_IO.OUT_FILE, FILE_NAME);
  242.     exception
  243.     when TEXT_IO.STATUS_ERROR =>
  244.         raise FILE_ALREADY_OPEN;
  245.     when TEXT_IO.USE_ERROR =>
  246.         raise CANNOT_CREATE_FILE;
  247.     when TEXT_IO.NAME_ERROR =>
  248.         TEXT_IO.PUT_LINE(" Cannot create " & FILE_NAME);
  249.         loop
  250.         begin
  251.             TEXT_IO.PUT(" Enter New File Name: ");
  252.             TEXT_IO.GET_LINE(INLINE, LAST);
  253.             TEXT_IO.CREATE(FD, TEXT_IO.OUT_FILE,
  254.               INLINE(INLINE'FIRST .. LAST));
  255.             exit;
  256.         exception
  257.             when TEXT_IO.NAME_ERROR =>
  258.             TEXT_IO.PUT_LINE(" Cannot create " &
  259.               INLINE(INLINE'FIRST .. LAST));
  260.             when others =>
  261.             raise ;
  262.         end;
  263.         end loop;
  264.     end OPEN;
  265.  
  266.     procedure OPEN(FILE_NAME : in LINE_DEFINITION.LINE) is
  267.     begin
  268.     OPEN(LINE_DEFINITION.CONVERT(FILE_NAME));
  269.     end OPEN;
  270.  
  271.     -- Close the output file
  272.     procedure CLOSE is
  273.     begin
  274.     TEXT_IO.CLOSE(FD);
  275.     exception
  276.     when TEXT_IO.STATUS_ERROR =>
  277.         raise FILE_NOT_OPEN;
  278.     end CLOSE;
  279.  
  280.     -- Write a line to the output file
  281.     procedure WRITE(FROM : in LINE_DEFINITION.LINE) is
  282.     begin
  283.     TEXT_IO.PUT_LINE(FD, LINE_DEFINITION.CONVERT(FROM));
  284.     exception
  285.     when TEXT_IO.STATUS_ERROR =>
  286.         raise FILE_NOT_OPEN;
  287.     when others =>
  288.         raise DISK_FULL;
  289.     end WRITE;
  290.  
  291.     procedure WRITE(FROM : in STRING) is
  292.     begin
  293.     WRITE(LINE_DEFINITION.CONVERT(FROM));
  294.     end WRITE;
  295.  
  296. end OUTPUT_FILE;
  297.  
  298. --===========================================================================
  299. -------------------------- PACKAGE INCLUDE_FILE -----------------------------
  300. --===========================================================================
  301.  
  302. -- The following package manipulates an object called an INCLUDE_FILE,
  303. -- which is a text file that is composed of objects of type LINE.
  304. -- LINEs can only be read from an INCLUDE_FILE.  An INCLUDE_FILE contains
  305. -- the following types of LINE objects:
  306. --    blank lines
  307. --    comment lines ('-' is the first character in the line)
  308. --    file names (a string of non-blank characters which does not
  309. --        begin with the character '-' or '@')
  310. --    include file names (a string of non-blank characters which
  311. --        begins with the character '@', where the '@' is used to
  312. --        prefix the file name within the include file and is not
  313. --        a part of the file name of the actual disk file)
  314. -- Include files may be nested several levels (defined by the constant
  315. -- NESTING_DEPTH).
  316. with LINE_DEFINITION;
  317. package INCLUDE_FILE is
  318.  
  319.     -- Maximum number of levels include files may be nested
  320.     NESTING_DEPTH     : constant NATURAL   := 40;
  321.  
  322.     -- Character which begins an include file name
  323.     INCLUDE_CHARACTER : constant CHARACTER := '@';
  324.  
  325.     -- Character which begins a comment line
  326.     COMMENT_CHARACTER : constant CHARACTER := '-';
  327.  
  328.     -- Open the include file (the LINE input string contains the leading '@')
  329.     -- Exceptions which may be raised: FILE_NOT_FOUND, NESTING_LEVEL_EXCEEDED
  330.     procedure OPEN(FILE_NAME : in LINE_DEFINITION.LINE);
  331.     procedure OPEN(FILE_NAME : in STRING);
  332.  
  333.     -- Read a LINE containing a file name from the include file
  334.     -- Exceptions which may be raised: FILE_NOT_OPEN, READ_PAST_END_OF_FILE
  335.     procedure READ(TO : out LINE_DEFINITION.LINE);
  336.  
  337.     -- Abort processing the include file (close all open files)
  338.     -- Exceptions which may be raised: FILE_NOT_OPEN
  339.     procedure STOP;
  340.  
  341.     -- Exceptional conditions
  342.     FILE_NOT_FOUND         : exception;
  343.     NESTING_LEVEL_EXCEEDED : exception;
  344.     FILE_NOT_OPEN          : exception;
  345.     READ_PAST_END_OF_FILE  : exception;
  346.     INCLUDE_FILE_EMPTY     : exception;
  347.  
  348. end INCLUDE_FILE;
  349.  
  350. with TEXT_IO;
  351. package body INCLUDE_FILE is
  352.  
  353.     -- File Descriptor for main include file
  354.     FD              : array(1 .. NESTING_DEPTH) of TEXT_IO.FILE_TYPE;
  355.     CURRENT_LEVEL   : NATURAL := 0;
  356.     NEXT_LINE       : LINE_DEFINITION.LINE;    -- next line to return by READ
  357.     NEXT_LINE_READY : BOOLEAN := FALSE;        -- indicates next line is
  358.                                                -- available
  359.  
  360.     -- Open the include file (the LINE input string contains the leading '@')
  361.     -- Exceptions which may be raised: FILE_NOT_FOUND, NESTING_LEVEL_EXCEEDED
  362.     procedure OPEN(FILE_NAME : in LINE_DEFINITION.LINE) is
  363.     begin
  364.     if CURRENT_LEVEL = NESTING_DEPTH then
  365.         raise NESTING_LEVEL_EXCEEDED;
  366.     else
  367.         CURRENT_LEVEL := CURRENT_LEVEL + 1;
  368.         TEXT_IO.OPEN(FD(CURRENT_LEVEL), TEXT_IO.IN_FILE,
  369.           FILE_NAME.CONTENT(2..FILE_NAME.LAST));
  370.     end if;
  371.     exception
  372.     when TEXT_IO.NAME_ERROR =>
  373.         TEXT_IO.PUT_LINE("Include File " &
  374.           LINE_DEFINITION.CONVERT(FILE_NAME) &
  375.               " not Found");
  376.         raise FILE_NOT_FOUND;
  377.     when others =>
  378.         TEXT_IO.PUT_LINE("Unexpected error with Include File " &
  379.           LINE_DEFINITION.CONVERT(FILE_NAME));
  380.         raise FILE_NOT_FOUND;
  381.     end OPEN;
  382.  
  383.     procedure OPEN(FILE_NAME : in STRING) is
  384.     begin
  385.     OPEN(LINE_DEFINITION.CONVERT(FILE_NAME));
  386.     end OPEN;
  387.  
  388.     -- Close the include file
  389.     -- Exceptions which may be raised: FILE_NOT_OPEN
  390.     procedure CLOSE is
  391.     begin
  392.     TEXT_IO.CLOSE(FD(CURRENT_LEVEL));
  393.     CURRENT_LEVEL := CURRENT_LEVEL - 1;
  394.     if CURRENT_LEVEL = 0 then
  395.         raise INCLUDE_FILE_EMPTY;
  396.     end if;
  397.     end CLOSE;
  398.  
  399.     -- Abort processing the include file
  400.     procedure STOP is
  401.     begin
  402.     while CURRENT_LEVEL > 0 loop
  403.         TEXT_IO.CLOSE(FD(CURRENT_LEVEL));
  404.         CURRENT_LEVEL := CURRENT_LEVEL - 1;
  405.     end loop;
  406.     end STOP;
  407.  
  408.     -- Read a LINE containing a file name from the include file
  409.     -- Exceptions which may be raised: FILE_NOT_OPEN, READ_PAST_END_OF_FILE
  410.     procedure READ(TO : out LINE_DEFINITION.LINE) is
  411.     INLINE : LINE_DEFINITION.LINE;
  412.     begin
  413.     loop
  414.         begin
  415.         TEXT_IO.GET_LINE(FD(CURRENT_LEVEL), INLINE.CONTENT,
  416.           INLINE.LAST);
  417.         if INLINE.LAST > 0 and INLINE.CONTENT(1) =
  418.           INCLUDE_CHARACTER then
  419.             OPEN(INLINE);
  420.         elsif (INLINE.LAST > 0 and INLINE.CONTENT(1) = COMMENT_CHARACTER) or
  421.           (INLINE.LAST = 0) then
  422.             null;    -- skip comment lines and empty lines
  423.         else
  424.             exit;
  425.         end if;
  426.         exception
  427.         when TEXT_IO.END_ERROR =>
  428.             CLOSE;
  429.         end;
  430.     end loop;
  431.     TO := INLINE;
  432.     end READ;
  433.  
  434. end INCLUDE_FILE;
  435.  
  436.